module Main (main) where

import Neural.FeedForward
import Neural.Neural
import System.Random
import Data.List
import Data.Graph.Inductive.Graphviz

mkPatterns rand = zip inputs outputs
                  where
                  inputs = map sort $ take 100 $ map (take 5) $ iterate (drop 5) rand
                  outputs = map (map tanh) inputs

mkFuncs makeCalcErrAndLearn patterns = map (uncurry makeCalcErrAndLearn) patterns

teach_f = foldl1' (.) . map teach
            where
            teach (calc, err, learn) = learn 0.02 . calc

err_f err = sum . map (^2) . err

{- main testing function to create train an introspect network -}
main = do gen<-getStdGen
          let rand = randomRs (-1.0, 1.0) gen :: [Double]
          let (makeCalcErrAndLearn, net) = makeNet rand 5 5 2 5
          let patterns = mkPatterns $ drop 3000 $ rand
          let mkcalcerrlearn = (makeCalcErrAndLearn standartActivations)
          let funcs = mkFuncs mkcalcerrlearn patterns
          let teach = teach_f funcs
          let err net = sum $ map (\(_, err, _) -> err_f err net) funcs
          let teached_nets = take 50 $ iterate teach net
          let last_net = last teached_nets
          let error_str = unlines $ map (show . err) teached_nets
          putStrLn error_str
          writeFile "teach.log" error_str
          writeFile "net.dot" $ graphviz' $ last_net
          let (i, o) = head patterns
          print i
          print o
          let (calc, _, _) = mkcalcerrlearn i o
          print $ getLOutputs $ calc last_net

